﻿//----------------------------------------------------------------------------------------------------
// The AStarSearch is a simple pathfinding implementation for visual nodes.
//----------------------------------------------------------------------------------------------------
package HG.Utilities
{
	import HG.Debug;
	
	import HG.GameService;
	import HG.Managers.LevelManager;
	import HG.Visual.VisualNode;
	import HG.Visual.VisualAttachPoint;
	
	import HG.Utilities.Pathfinding.Pathfinder;
	import HG.Utilities.Pathfinding.INode;
	import HG.Visual.VisualConnection;
	
	public class AStarSearch
	{
		static var m_INodes:Array = new Array();
		static var m_VNodes:Array = new Array();
		
		var m_levelManager:LevelManager;
		
		var m_fromNode:VisualNode;
		var m_toNode:VisualNode;
		
		//----------------------------------------------------------------------------------------------------
		public function AStarSearch(fromNode:VisualNode, toNode:VisualNode)
		{
			m_levelManager = GameService.GetInstance().GetLevelManager();
			
			m_fromNode = toNode;
			m_toNode = fromNode;
		}
		
		//----------------------------------------------------------------------------------------------------
		public function Begin():Array
		{
			
			//TODO: why is the distance of the path correct when saving, but the AI path wrong, when playing?
			
			var pathOutput:Array = Pathfinder.findPath(GetINode(m_fromNode), GetINode(m_toNode), GetConnectedINodes);
		
			var output:Array = new Array();
			
			var index:Number = 0;
			var listLength:Number = pathOutput.length;
			for (index = 0; index < listLength; ++index)
			{
				output.push(GetVisualNode(pathOutput[index]));
			}
			
			return output;
		}
		
		//----------------------------------------------------------------------------------------------------
		public function GetVisualNode(node:INode):VisualNode
		{
			return m_VNodes[node.visNode.GetID()];
		}
		
		//----------------------------------------------------------------------------------------------------
		public function GetINode(visNode:VisualNode):INode
		{
			if (m_INodes[visNode.GetID()] != undefined)
			{
				return m_INodes[visNode.GetID()];
			}
			
			var visAttach:VisualAttachPoint = visNode.GetSource();
			
			var outNode:INode = new INode();
			
			outNode.f = 0;
			outNode.g = 0;
			outNode.h = 0;
			//outNode.parentNode
			outNode.traversable = true;
			outNode.x = visAttach.GetX();
			outNode.y = visAttach.GetY();
			outNode.visNode = visNode;
			
			m_INodes[visNode.GetID()] = outNode;
			m_VNodes[visNode.GetID()] = visNode;
			
			return outNode;
		}
		
		//----------------------------------------------------------------------------------------------------
		public function GetConnectedINodes(node:INode):Array
		{
			var visConnections:Array = node.visNode.GetConnections();
			var output:Array = new Array();
			
			var index:Number = 0;
			var listLength:Number = visConnections.length;
			
			for (index = 0; index < listLength; ++index)
			{
				var visNode:VisualNode = m_levelManager.GetVisualNode(visConnections[index]);
				output.push(GetINode(visNode));
			}
			
			return output;
		}
		
		//----------------------------------------------------------------------------------------------------
	}
}








